/**
 * Copyright 2014 opencxa.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cxa.rpc.cloud.configurationConsole.userManagement;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

import org.cxa.misc.ClassUtils;
import org.cxa.rpc.cloud.client.TransientDevice;
import org.cxa.rpc.cloud.server.components.authentication.User;
import org.cxa.rpc.messages.ResponseRpcMessage;


/**
 * @author Christopher Armenio
 *
 */
public class UserTableModel extends AbstractTableModel
{
	private static final long serialVersionUID = 1062255885489118281L;
	@SuppressWarnings("serial")
	private static final LinkedHashMap<String, Class<?>> COLS = new LinkedHashMap<String, Class<?>>()
	{{
		put("ID", Integer.class);
		put("Email", String.class);
		put("Groups", String.class);
		put("Enabled", Boolean.class);
	}};
	
	
	private final TransientDevice tDev;
	private final List<User> localUserList = new ArrayList<User>();
	
	
	public UserTableModel(TransientDevice tDevIn)
	{
		this.tDev = tDevIn;
	}
	
	
	public void refreshFromServer()
	{
		ResponseRpcMessage resp = this.tDev.sendRequest("/sys/auth", "getUserList");
		if( !resp.getWasSuccessful() )
		{
			JOptionPane.showMessageDialog(null, String.format("Error retrieving user list:\n%s", resp.getException().getFormattedErrorString()));
			return;
		}
		
		this.localUserList.clear();
		List<?> users_raw = (List<?>)resp.getReturnValue(List.class);
		for( Object currUser_raw : users_raw ) 
		{
			User currUser = (User)ClassUtils.classFromPojoMap(currUser_raw, User.class);
			if( currUser == null ) continue;
			this.localUserList.add(currUser);
		}
		this.fireTableDataChanged();
	}
	
	
	public User getUserAtRow(int rowIn)
	{
		return this.localUserList.get(rowIn);
	}
	
	
	public void deleteUserByEmail(String emailAddrIn)
	{
		// first, make sure _we_ know about this user
		User targetUser = null;
		for( User currUser : this.localUserList )
		{
			if( currUser.getEmail().equals(emailAddrIn) )
			{
				targetUser = currUser;
				break;
			}
		}
		if( targetUser == null ) return;
	
		// if we made it here, we found the user...delete it on the server
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("email", emailAddrIn);
		ResponseRpcMessage resp = this.tDev.sendRequest("/sys/auth", "deleteUserByEmail", params);
		if( !resp.getWasSuccessful() )
		{
			JOptionPane.showMessageDialog(null, String.format("Error deleting user:\n%s", resp.getException().getFormattedErrorString()));
			return;
		}
		
		// if we made it here, we deleted it on the server, now delete it locally
		this.localUserList.remove(targetUser);
		this.fireTableDataChanged();
	}
	
	
	@Override
	public String getColumnName(int colIndexIn)
	{
		int currIndex = 0;
		Iterator<String> it = COLS.keySet().iterator();
		while( it.hasNext() )
		{
			String currVal = it.next();
			if( currIndex++ == colIndexIn ) return currVal;
		}
		return null;
	}
	
	
	@Override
	public int getRowCount()
	{
		return this.localUserList.size(); 
	}
	

	@Override
	public int getColumnCount()
	{
		return COLS.size();
	}

	
	@Override
	public Object getValueAt(int rowIndexIn, int colIndexIn)
	{
		User selectedUser = this.localUserList.get(rowIndexIn);
		if( selectedUser == null ) return null;
		
		Object retVal = null;
		switch( colIndexIn )
		{
			case 0:
				retVal = selectedUser.getId();
				break;
			
			case 1:
				retVal = selectedUser.getEmail();
				break;
				
			case 2:
				StringBuilder sb = new StringBuilder();
				for(Integer currGroupId : selectedUser.getGroups())
				{
					sb.append(currGroupId);
					sb.append(", ");
				}
				sb.delete(sb.length()-2, sb.length());
				retVal = sb.toString();
				break;
				
			case 3:
				retVal = selectedUser.isEnabled();
				break;
		}
		return retVal;
	}
	
	
	@Override
	public Class<?> getColumnClass(int colIndexIn)
	{
		int currIndex = 0;
		Iterator<Class<?>> it = COLS.values().iterator();
		while( it.hasNext() )
		{
			Class<?> currType = it.next();
			if( currIndex++ == colIndexIn ) return currType;
		}
		return null;
	}


	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex)
	{
		// TODO Auto-generated method stub
		return false;
	}


	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex)
	{
		// TODO Auto-generated method stub
		
	}
}
